using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Windows.Forms;
using BassWrapper;
using Tags;

namespace TagReader
{

	[
	Guid("C0E31022-527D-4571-978F-7C70CDBE4359")
	]
	// must be a class as structas are not marshaled properly
	public class TrackInfo 
	{
		public string ArtistName;
		public string TrackTitle;
		public string AlbumTitle;
		public int Year;
		public string Genre;
		public int TrackNumber;
		public int TotalTracks;
		public int DiscNumber;
		public int TotalDiscs;
		public string Comment;
		public string FileName;
		public double TrackLength;

		public TrackInfo() 
		{
			ArtistName = String.Empty;
			TrackTitle = String.Empty;
			AlbumTitle = String.Empty;
			Year = 0;
			Genre = String.Empty;
			TrackNumber = 0;
			TotalTracks = 0;
			DiscNumber = 0;
			TotalDiscs = 0;
			Comment = String.Empty;
			FileName = String.Empty;
			TrackLength = 0.0;
		}

		public TrackInfo(string filename) 
			: this()
		{
			FileName = filename;
		}
	}

	[
	Guid("5871A89C-C2AD-409d-A078-EC6ACD75EAB6"),
	InterfaceType(ComInterfaceType.InterfaceIsIDispatch)
	]
	public interface _TagReader
	{
		TrackInfo ReadTrackInfoStream(int stream);
		TrackInfo ReadTrackInfoFile(string filename);
	}

	[
	Guid("9ADE510D-3165-4168-B009-B45B5C8B691B"),
	ClassInterface(ClassInterfaceType.None),
	ProgId("TagReader")
	]
	public class TagReader : _TagReader	
	{

		private IList plugins = null;

		private void InitPlugins() 
		{
			//System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(@"C:\BASS");
			foreach (string file in System.IO.Directory.GetFiles(@"C:\BASS", "bass*.dll"))
			{
				if (file.EndsWith("bass.dll")) // skip bass.dll
				{
					continue;
				}

				int plugin = Bass.BASS_PluginLoad(file,0);
				if (plugin != 0) {
					plugins.Add(plugin);
				}
			}
		}

		public TagReader() 
		{
			plugins = new ArrayList();

			try 
			{
				Bass.BASS_Init(-1, 48000, 2, IntPtr.Zero, null);
			} 
			catch (Exception) 
			{
				// error;
			}

			InitPlugins();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~TagReader()
		{
			Bass.BASS_PluginFree(0);
			// close bass
			Bass.BASS_Stop();
			Bass.BASS_Free();
		}

		public TrackInfo ReadTrackInfoStream(int stream) 
		{
			TAG_INFO tagInfo = new TAG_INFO();
			TrackInfo info = new TrackInfo();
			if (BassTags.BASS_TAG_GetFromFile(stream, tagInfo)) 
			{
//				public int TotalTracks;
//				public int DiscNumber;
//				public int TotalDiscs;

				info.AlbumTitle = tagInfo.album;
				info.ArtistName = tagInfo.artist;
				try 
				{
					info.TrackNumber = int.Parse(tagInfo.track);
				} 
				catch (Exception) 
				{
					info.TrackNumber = 0;
				}
				try 
				{
					info.Year = int.Parse(tagInfo.year);
				} 
				catch (Exception)
				{
					info.Year = 0;
				}
				info.TrackTitle = tagInfo.title;
				info.Comment = tagInfo.comment;
				info.Genre = tagInfo.genre;
				info.TrackLength = Bass.BASS_ChannelBytes2Seconds(stream, Bass.BASS_ChannelGetLength(stream, 0));
			}
			return info;
		}

		public TrackInfo ReadTrackInfoFile(string filename) 
		{
			int stream = Bass.BASS_StreamCreateFile(false, filename, 0, 0, 
				(int) (BASSStream.BASS_SAMPLE_FLOAT | BASSStream.BASS_DEFAULT | BASSStream.BASS_UNICODE));
			if (stream != 0) 
			{
				return ReadTrackInfoStream(stream);
			}
			return new TrackInfo(filename);
		}

	}
}
